package com.fattyCorps.battle.service.battle;

import com.fattyCorps.battle.service.battle.data.BattleHero;
import com.fattyCorps.common.enums.battle.triggerCondition.EBehaviorCondition;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

// 一个回合
@Slf4j
public class Round {
    // 当前回合数
    private int no = 1;
    private Battle battle;

    public Round(int no, Battle battle) {
        this.no = no;
        this.battle = battle;
    }

    // 执行回合
    // 每个英雄出手完 回合结束
    public void invoke() {
        onStart();

        int maxLoop = 999;
        int loopIndex = 0;

        while (loopIndex < maxLoop) {
            BattleHero nextActiveHero = getNextAttackHero();
            if (nextActiveHero == null) {
                break;
            }

            battle.setCurActiveHero(nextActiveHero);

            beforeHeroActive(nextActiveHero);
            heroActive(nextActiveHero);
            afterHeroActive(nextActiveHero);

            loopIndex ++;
        }

        if (loopIndex >= maxLoop) {
            // 出错了
            return;
        }

        onOver();
    }

    private void onStart() {
//        log.info("进入回合" + this.no);
        battle.onEvent(EBehaviorCondition.BeforeRoundBegin);
    }

    private void onOver() {
        List<BattleHero> battleHeroes = allHeroes();
        for (BattleHero battleHero : battleHeroes) {
            battleHero.setRoundActive(false);
        }

        battle.onEvent(EBehaviorCondition.AfterRoundEnd);
    }

    // 英雄行动前
    private void beforeHeroActive(BattleHero hero) {
        battle.onEvent(EBehaviorCondition.BeforeHeroActive, hero);
        battle.onEvent(EBehaviorCondition.BeforeSelfActive, hero);
    }

    // 英雄行动
    private void heroActive(BattleHero hero) {
        hero.setRoundActive(true);
        hero.active();
    }

    // 英雄出手后，处理非自己的技能触发
    private void afterHeroActive(BattleHero hero) {
        battle.onEvent(EBehaviorCondition.AfterHeroActive, hero);
        battle.onEvent(EBehaviorCondition.AfterSelfActive, hero);
    }

    // 获取下个出手攻击的英雄
    private BattleHero getNextAttackHero() {
        // 根据速度重新排列出手顺序
        List<BattleHero> battleHeroes = allHeroes();

        Collections.sort(battleHeroes, new Comparator<BattleHero>() {
            @Override
            public int compare(BattleHero o1, BattleHero o2) {
                return (int)(Float.valueOf(o2.getHero().getPropComp().getSpeed()) - Float.valueOf(o1.getHero().getPropComp().getSpeed()));
            }
        });

        // 获取最新没有出手的英雄
        for (BattleHero battleHero : battleHeroes) {
            if (!battleHero.isRoundActive()) {
                return battleHero;
            }
        }

        return null;
    }

    public List<BattleHero> allHeroes() {
        List<BattleHero> battleHeroes = new ArrayList<>();
        battleHeroes.addAll(battle.getBattleData().getLeft().getHeroes());
        battleHeroes.addAll(battle.getBattleData().getRight().getHeroes());

        return battleHeroes;
    }
}
